using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class My_SceneManager : MonoBehaviour
{
    private string logicName = "[SceneLogic]";

    private void Awake()
    {
        SceneManager.activeSceneChanged += OnActiveSceneChanged;
    }

    /// <summary>
    /// 场景切换的回调
    /// </summary>
    /// <param name="s1"></param>
    /// <param name="s2"></param>
    private void OnActiveSceneChanged(Scene s1, Scene s2)
    {
        if (!s1.isLoaded || !s2.isLoaded)
            return;

        SceneLogic sceneLogic_1 = GetSceneLogic(s1);
        SceneLogic sceneLogic_2 = GetSceneLogic(s2);

        sceneLogic_1?.OnInActive();
        sceneLogic_2?.OnActive();
    }

    public void SetSceneActive(string _sceneName)
    {
        Scene scene = SceneManager.GetSceneByName(_sceneName);
        SceneManager.SetActiveScene(scene);
    }

    #region 场景加载模块

    /// <summary>
    /// 以叠加模式加载场景
    /// </summary>
    /// <param name="_sceneName"></param>
    /// <param name="_luaName"></param>
    public void LoadScene(string _sceneName, string _luaName)
    {
        Manager.Resources.LoadScene(_sceneName, (UnityEngine.Object obj) =>
        {
            StartCoroutine(StartLoadScene(_sceneName, _luaName, LoadSceneMode.Additive));
        });
    }

    /// <summary>
    /// 切换场景
    /// </summary>
    /// <param name="_sceneName"></param>
    /// <param name="_luaName"></param>
    public void ChangeScene(string _sceneName, string _luaName)
    {
        Manager.Resources.LoadScene(_sceneName, (UnityEngine.Object obj) =>
        {
            StartCoroutine(StartLoadScene(_sceneName, _luaName, LoadSceneMode.Single));
        });
    }

    /// <summary>
    /// 判断场景是否已经加载
    /// </summary>
    /// <param name="_sceneName"></param>
    /// <returns></returns>
    private bool IsLoadedScene(string _sceneName)
    {
        Scene scene = SceneManager.GetSceneByName(_sceneName);
        return scene.isLoaded;
    }

    IEnumerator StartLoadScene(string _sceneName, string _luaName, LoadSceneMode _loadMode)
    {
        if(IsLoadedScene(_sceneName))
            yield break;

        AsyncOperation async = SceneManager.LoadSceneAsync(_sceneName, _loadMode);
        async.allowSceneActivation = true;
        yield return async;

        Scene scene = SceneManager.GetSceneByName(_sceneName);
        GameObject go = new GameObject(logicName);
        SceneManager.MoveGameObjectToScene(go, scene);
        SceneLogic sceneLogic = go.AddComponent<SceneLogic>();
        sceneLogic.sceneName = _sceneName;
        sceneLogic.Init(_luaName);
        sceneLogic.OnEnter();
    }

    #endregion

    #region 场景卸载模块

    public void UnLoadSceneAsync(string _sceneName) 
    {
        StartCoroutine(UnLoadScene(_sceneName)); 
    }

    private IEnumerator UnLoadScene(string _sceneName)
    {
        Scene scene = SceneManager.GetSceneByName(_sceneName);

        if(!IsLoadedScene(_sceneName))
        {
            Debug.LogError("Scene is not loaded");
            yield break;
        }

        SceneLogic sceneLogic = GetSceneLogic(scene);
        sceneLogic.OnQuit();
        AsyncOperation async = SceneManager.UnloadSceneAsync(_sceneName);
        yield return async;
    }

    private SceneLogic GetSceneLogic(Scene scene)
    {
        GameObject[] gameObjects = scene.GetRootGameObjects();

        foreach (GameObject gameObject in gameObjects) 
        {
            if(gameObject.name.CompareTo(logicName) == 0)
            {
                SceneLogic sceneLogic = gameObject.GetComponent<SceneLogic>();
                return sceneLogic;
            }
        }

        return null;
    }

    #endregion
}
